#include "util.hpp"
#include "Online.hpp"
#include "room.hpp"
#include "match.hpp"
#include "session.hpp"
#include "server.hpp"

std::string mysql_host = "101.34.254.139";
std::string mysql_user = "lw";
std::string mysql_passwd = "Liwei200408#";
std::string mysql_db = "gobang";
uint16_t Mysql_port = 3306;

using webserver_t = websocketpp::server<websocketpp::config::asio>;
const uint16_t BindPort = 8080;

// std::weak_ptr<void>
void http_callback(webserver_t* psrv, websocketpp::connection_hdl hd1)
{
    // 返回一个http页面
    webserver_t::connection_ptr conn = psrv->get_con_from_hdl(hd1);
    std::cout << "body: " << conn->get_request_body() << std::endl;

    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>Hello World</h1></body></html>";
    conn->set_body(body);
    conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::value::ok);
}
void open_callback(webserver_t* psrv, websocketpp::connection_hdl hd1)
{
    std::cout << "握手成功\n";
}
void close_callback(webserver_t* psrv, websocketpp::connection_hdl hd1)
{
    std::cout << "连接断开\n";
}
void message_callback(webserver_t* psrv, websocketpp::connection_hdl hd1, webserver_t::message_ptr msg)
{
    std::cout << "msg: " << msg->get_payload() << std::endl;
    webserver_t::connection_ptr conn = psrv->get_con_from_hdl(hd1);

    std::string rsp = "client say# " + msg->get_payload();
    conn->send(rsp, websocketpp::frame::opcode::value::text);
}

void StartWebsocket()
{
    // 1、初始化服务器对象
    webserver_t server;
    // server.set_timer 定时任务的取消是立即执行
    // 2、设置日志等级
    server.set_access_channels(websocketpp::log::alevel::none);
    // 3、初始化asio调度器并设置地址重用
    server.init_asio();
    server.set_reuse_addr(true);
    // 4、设置回调函数
    server.set_open_handler(std::bind(open_callback, &server, std::placeholders::_1));
    server.set_close_handler(std::bind(close_callback, &server, std::placeholders::_1));
    server.set_http_handler(std::bind(http_callback, &server, std::placeholders::_1));
    server.set_message_handler(std::bind(message_callback, &server, std::placeholders::_1, std::placeholders::_2));

    server.listen(BindPort);
    server.start_accept();
    server.run();
}

int main()
{
    StartWebsocket();
    return 0;
}

// void testonline()
// {
//     // Online_User_Manage on;
//     // int uid1 = 1;
//     // int uid2 = 2;
//     // websocketpp::server<websocketpp::config::asio>::connection_ptr cp1;
//     // websocketpp::server<websocketpp::config::asio>::connection_ptr cp2;
//     // on.enter_game_hall(uid1, cp1);
//     // on.enter_game_room(uid2, cp2);

//     // std::cout << "on.is_in_game_hall(uid2): " << on.is_in_game_hall(uid2) << std::endl;
//     // std::cout << "on.is_in_game_room(uid1): " << on.is_in_game_room(uid1) << std::endl;
//     // std::cout << "on.is_in_game_room(uid2): " << on.is_in_game_room(uid2) << std::endl;
//     // std::cout << "on.is_in_game_hall(uid1): " << on.is_in_game_hall(uid1) << std::endl;

//     // on.exit_game_hall(uid1);
//     // on.exit_game_room(uid2);
//     // std::cout << "on.is_in_game_hall(uid1): " << on.is_in_game_hall(uid1) << std::endl;
//     // std::cout << "on.is_in_game_hall(uid2): " << on.is_in_game_hall(uid2) << std::endl;
//     // std::cout << "on.is_in_game_room(uid1): " << on.is_in_game_room(uid1) << std::endl;
//     // std::cout << "on.is_in_game_room(uid2): " << on.is_in_game_room(uid2) << std::endl;

//     Json::Value r;
//     r["a"] = "";
//     r["a"] = "haha";
//     printf("r[\"a\"] = %s\n", r["a"].asString().c_str());
// }

// void testroom()
// {
//     // Online_User_Manage oum;
//     // UserCtl uc;
//     // // Room room(1, &uc, &oum);

//     // RoomManage rm(&uc, &oum);
//     // rm.create_room(1, 2);
//     // room_ptr rp1 = rm.get_room_by_userid(1);
//     // std::cout << "get_room_by_userid(1), roomid: " << rp1->GetRoomid() << std::endl;

//     // room_ptr rp2 = rm.get_room_by_userid(2);
//     // std::cout << "get_room_by_userid(2), roomid: " << rp2->GetRoomid() << std::endl;

//     // room_ptr rp3 = rm.get_room_by_roomid(1);
//     // std::cout << "get_room_by_roomid(1), roomid: " << rp3->GetRoomid() << std::endl;

//     // rm.remove_room_user(1);
//     // rm.remove_room_user(2);
// }

// uint16_t BindPort = 8080;
// void testserver()
// {
//     std::string host = "101.34.254.139";
//     std::string user = "lw";
//     std::string passwd = "Liwei197811#";
//     std::string db = "gobang";
//     gobang_server server(host, user, passwd, db);
//     server.start(BindPort);
    
// }

// void testmysql()
// {
//     UserCtl uc(mysql_host, mysql_user, mysql_passwd, mysql_db);
//     Json::Value info;
//     std::string info_str;
//     if(uc.SelectUserByName(info, "lw"))
//     {
//         json_util::serialize(info, info_str);
//         std::cout << info_str << std::endl;
//     }
//     else  
//     {
//         std::cout << "SelectUserByName error" << std::endl;
//     }
    
// }

// int main()
// {
//     testserver();
//     return 0;
// }



// std::string mysql_host = "101.34.254.139";
// std::string mysql_user = "lw";
// std::string mysql_passwd = "Liwei197811#";
// std::string mysql_db = "gobang";
// uint16_t Mysql_port = 3306;

// void testmysql()
// {
//     Mysql my(mysql_host, mysql_user, mysql_passwd, mysql_db, 3306);

//     my.MysqlInit();
//     my.MysqlQuery("select * from test");
//     MYSQL_RES* res = mysql_store_result(my.GetMy());
//     int col_num = mysql_num_fields(res);

//     printf("col_num: %d\n", col_num);
// }

// void testsplit()
// {
//     std::vector<std::string> v;
//     StringSplit::split("abc\r\ndefg\r\nhij\r\nghzzz\r\n\r\n\r\n", "\r\n", v);

//     for (std::string s : v)
//     {
//         std::cout << s << std::endl;
//     }
// }

// void testFile()
// {
//     std::string msg;
//     Fileop::ReadFile("./example.txt", msg);
//     std::cout << msg;

//     Fileop::WriteFile("./example.txt", "heelo");
//     Fileop::WriteFile("./example.txt", "haha");
// }

// void testuserctl()
// {
//     UserCtl uc;
//     Json::Value root;
//     root["username"] = "李四";
//     root["password"] = "123456";

//     // uc.SelectUserByName(root, "张三");

//     // ------------------------------测试插入
//     // uc.InsertUser(root);


//     // uc._my.MysqlQuery("select id, score, total_count, win_count from user where username='张三' and password=sha2('123456', 256)");

//     // MYSQL_RES* res = mysql_store_result(uc._my.GetMy());

//     // MYSQL_ROW row = mysql_fetch_row(res);
//     // int col_num = mysql_num_fields(res);
//     // std::cout << "row: " << row << std::endl;
//     // if(row)
//     // {root["id"] = row[0];
//     // root["score"] = row[1];
//     // root["total_count"] = row[2];
//     // root["win_count"] = row[3];}

//     // ----------------------------------测试登录
//     // uc.Login(root);
//     // uc.SelectUserById(root, 3);
//     // uc.Win(3);
//     // uc.Win(3);
//     uc.Lose(3);
//     uc.Lose(3);
//     uc.Lose(3);
    
//     // printf("id = %d, score = %d\n", root["id"].asInt(), root["score"].asInt());
// }

// int main()
// {
//     testuserctl();
//     return 0;
// }



// int main()
// {
//     Json::StyledWriter sw;
//     Json::Value root;
//     Json::CharReaderBuilder crb;
//     Json::CharReader* pcReader = crb.newCharReader();
//     pcReader->parse()

//     return 0;
// }

// int main()
// {
//     LOG(3, "%s, %d, %d", "aa", 3, 4);
//     return 0;
// }
